home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / STDLIB.PAK / ICECREAM.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  5KB  |  196 lines

  1. /**************************************************************************
  2.  *
  3.  * icecream.cpp - priority queue example program. Section 11.3.1
  4.  *
  5.  * $Id: icecream.cpp,v 1.5 1995/08/29 19:01:39 oberg Exp $
  6.  *
  7.  * $$RW_INSERT_HEADER "slyrs.cpp"
  8.  *
  9.  **************************************************************************/
  10.  
  11. # include <vector>
  12. # include <queue>
  13.  
  14. # include <iostream.h>
  15. using namespace std;
  16.  
  17. //
  18. //    class event
  19. //    execution event in a descrete event driven simulation
  20. //
  21.  
  22. class event {
  23. public:
  24.     // construct sets time of event
  25.     event (unsigned int t) : time(t) { };
  26.     
  27.     // time is a public data field
  28.     const unsigned int time;
  29.     
  30.     // execute event my invoking this method
  31.     virtual void processEvent() = 0;
  32. };
  33.  
  34. inline void destroy(event **) {}
  35.  
  36. struct eventComparison {
  37.     bool operator () (event * left, event * right)
  38.         { return left->time > right->time; }
  39. };
  40.  
  41. //
  42. //    class simulation
  43. //        framework for discrete event-driven simulations
  44. //    written by Tim Budd, for Rogue Wave, 1995
  45. //
  46.  
  47. class simulation {
  48. public:
  49.         // constructor
  50.     simulation () : eventQueue(), time(0) {}
  51.     
  52.         // start and run simulation
  53.     void run ();
  54.     
  55.         // return current time
  56.     unsigned int time;
  57.     
  58.         // schedule a future event
  59.     void  scheduleEvent (event * newEvent)
  60.         { eventQueue.push(newEvent); }
  61.     
  62. protected:
  63.     priority_queue<event*, vector<event *>, eventComparison> eventQueue;
  64. };
  65.  
  66. void simulation::run()
  67. {
  68.     while (! eventQueue.empty()) {
  69.         event * nextEvent = eventQueue.top();
  70.         eventQueue.pop();
  71.         time = nextEvent->time;
  72.         nextEvent->processEvent();
  73.         delete nextEvent;
  74.         }
  75. }
  76.  
  77. //
  78. //    ice cream store simulation
  79. //
  80.  
  81. class storeSimulation : public simulation {
  82. public:
  83.     storeSimulation()
  84.         : freeChairs(35), profit(0.0), simulation() { }
  85.         
  86.     bool canSeat(unsigned int numberOfPeople);
  87.     void order(unsigned int numberOfScoops);
  88.     void leave(unsigned int numberOfPeople);
  89.     
  90.         // data fields
  91.     unsigned int freeChairs;
  92.     double profit;    
  93. } theSimulation;
  94.  
  95. class arriveEvent : public event {
  96. public:
  97.     arriveEvent (unsigned int time, unsigned int groupSize)
  98.         : event(time), size(groupSize) { }
  99.     virtual void processEvent();
  100. private:
  101.     unsigned int size;
  102. };
  103.  
  104. class orderEvent : public event {
  105. public:
  106.     orderEvent (unsigned int time, unsigned int groupSize)
  107.         : event(time), size(groupSize) { }
  108.     virtual void processEvent();
  109. private:
  110.     unsigned int size;
  111. };
  112.  
  113. class leaveEvent : public event {
  114. public:
  115.     leaveEvent (unsigned int time, unsigned int groupSize)
  116.         : event(time), size(groupSize) { }
  117.     virtual void processEvent();
  118. private:
  119.     unsigned int size;
  120. };
  121.  
  122. int irand(int n)
  123.     // return random integer between 0 and n
  124. { return (rand()/10) % n; }
  125.  
  126. void arriveEvent::processEvent()
  127. {
  128.     if (theSimulation.canSeat(size))
  129.         theSimulation.scheduleEvent(new orderEvent(time + 1 + irand(4), size));
  130. }
  131.  
  132. void orderEvent::processEvent()
  133. {
  134.         // each person orders some number of scoops
  135.     for (int i = 0; i < size; i++)
  136.         theSimulation.order(1 + irand(4));
  137.         // then we schedule the leave event
  138.     theSimulation.scheduleEvent(new leaveEvent(time + 1 + irand(10), size));
  139. }
  140.  
  141. void leaveEvent::processEvent()
  142. {
  143.     theSimulation.leave(size);
  144. }
  145.  
  146. bool storeSimulation::canSeat(unsigned int numberOfPeople)
  147.     // if sufficient room then seat customers
  148. {
  149.     cout << "Time: " << time;
  150.     cout << " group of " << numberOfPeople << " customers arrives";
  151.     if (numberOfPeople < freeChairs) {
  152.         cout << " is seated" << endl;
  153.         freeChairs -= numberOfPeople;
  154.         return true;
  155.         }
  156.     else {
  157.         cout << " no room, they leave" << endl;
  158.         return false;
  159.         }
  160. }
  161.  
  162. void storeSimulation::order(unsigned int numberOfScoops)
  163.     // service icecream, compute profits
  164. {
  165.     cout << "Time: " << time;
  166.     cout << " serviced order for " << numberOfScoops << endl;
  167.     profit += 0.35 * numberOfScoops;
  168. }
  169.  
  170. void storeSimulation::leave(unsigned int numberOfPeople)
  171.     // people leave, free up chairs
  172. {
  173.     cout << "Time: " << time;
  174.     cout << " group of size " << numberOfPeople << " leaves" << endl;
  175.     freeChairs += numberOfPeople;
  176. }
  177.  
  178. int main() {
  179.     cout << "Ice Cream Store simulation from Chapter 9"  << endl;
  180.         // load queue with some number of initial events
  181.     unsigned int t = 0;
  182.     while (t < 20) {
  183.         t += irand(6);
  184.         cout << "pumping queue with event " << t << endl;
  185.         theSimulation.scheduleEvent(new arriveEvent(t, 1 + irand(4)));
  186.         }
  187.     
  188.         // run the simulation    
  189.     theSimulation.run();
  190.     cout << "Total profits " << theSimulation.profit << endl;
  191.     
  192.     cout << "End of ice cream store simulation" << endl;
  193.     return 0;
  194. }
  195.     
  196.